package by.gravity.pvh.fragments;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.holoeverywhere.app.Fragment;
import org.holoeverywhere.widget.Button;
import org.holoeverywhere.widget.EditText;
import org.holoeverywhere.widget.LinearLayout;
import org.holoeverywhere.widget.RadioButton;
import org.holoeverywhere.widget.Spinner;
import org.holoeverywhere.widget.TextView;
import org.holoeverywhere.widget.Toast;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.LinearLayout.LayoutParams;
import android.widget.RadioGroup;
import by.gravity.pvh.MainActivity;
import by.gravity.pvh.R;
import by.gravity.pvh.data.PreferenceDataManager;
import by.gravity.pvh.data.SQLDataManager;
import by.gravity.pvh.data.SQLDataManager.TypeOrder;
import by.gravity.pvh.data.SQLDataManager.onLoadCompleteListener;
import by.gravity.pvh.data.SQLDataManager.onLoadModelCompleteListener;
import by.gravity.pvh.model.BalconyBlockModel;
import by.gravity.pvh.model.BalconyRamaModel;
import by.gravity.pvh.model.CommonModel;
import by.gravity.pvh.model.DoorModel;
import by.gravity.pvh.model.WindowModel;
import by.gravity.pvh.utils.DialogUtil;
import by.gravity.pvh.utils.DialogUtil.onEditCompleteListener;
import by.gravity.pvh.utils.DialogUtil.onSelectCompleteListener;
import by.gravity.pvh.utils.StringUtil;
import by.gravity.pvh.utils.math.Parser;
import by.gravity.pvh.utils.math.SyntaxException;

import com.google.gson.Gson;

public abstract class CommonFragment extends Fragment {

	private static final String DATE_FORMAT = "dd MMMM yyyy HH:mm";

	private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);

	private EditText rateUsd;

	private TextView lastTimeUpdate;

	private LinearLayout windowImage;

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {

		super.onActivityCreated(savedInstanceState);
		setHasOptionsMenu(true);
		rateUsd = (EditText) getView().findViewById(R.id.rateUsd);
		lastTimeUpdate = (TextView) getView().findViewById(R.id.lastUpdatTime);

		Button calculateButton = (Button) getView().findViewById(R.id.calculateBtn);
		calculateButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				String formula = getFormula();
				try {
					if (formula != null) {
						double result = Parser.parse(formula).value();
						DialogUtil.showConfirmDialog(getActivity(), R.string.workPrice,
								getDialogMessage(formula, Math.round(result), rateUsd.getText().toString(), false));
					}

				} catch (SyntaxException e) {
					e.printStackTrace();
					Toast.makeText(getActivity(), R.string.calculateError, Toast.LENGTH_SHORT).show();
				}
			}
		});

		calculateButton.setOnLongClickListener(new OnLongClickListener() {

			@Override
			public boolean onLongClick(View v) {

				String formula = getFormula();

				try {
					if (formula != null) {
						double result = Parser.parse(formula).value();
						DialogUtil.showConfirmDialog(getActivity(), R.string.workPrice,
								getDialogMessage(formula, Math.round(result), rateUsd.getText().toString(), true));
					}

				} catch (SyntaxException e) {
					e.printStackTrace();
					Toast.makeText(getActivity(), R.string.calculateError, Toast.LENGTH_SHORT).show();
				}
				return false;
			}
		});
		if (PreferenceDataManager.getLastUpdateTime(getActivity()) == 0) {
			lastTimeUpdate.setText(getString(R.string.never));
		} else {
			lastTimeUpdate.setText(simpleDateFormat.format(new Date(PreferenceDataManager.getLastUpdateTime(getActivity()))));
		}

		rateUsd.setText(PreferenceDataManager.getRate(getActivity()));

		windowImage = (LinearLayout) getView().findViewById(R.id.windowImageLayout);

	}

	protected void showWindowImage(int count) {
		showWindowImage(count, null);
	}

	protected void showWindowImage(int count, List<String> values) {
		if (count >= 2) {
			float weight = 1;
			if (count == 2) {
				weight = 0.5f;
			} else if (count == 3) {
				weight = 0.33f;
			} else if (count == 4) {
				weight = 0.25f;
			}
			windowImage.setVisibility(View.VISIBLE);
			windowImage.removeAllViews();
			for (int i = 0; i < count; i++) {
				final Button windowImageButton = new Button(getActivity());
				windowImageButton.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						windowImageButton.setText(getNextWindowButtonName(windowImageButton));
					}
				});
				windowImageButton.setLayoutParams(new android.widget.LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, weight));
				if (values != null) {
					windowImageButton.setText(values.get(i));
				} else {
					windowImageButton.setText(getString(R.string.typeDeaf));
				}
				windowImage.addView(windowImageButton);
			}

		} else {
			windowImage.setVisibility(View.GONE);
		}
	}

	protected String getNextWindowButtonName(Button button) {
		if (button.getText().equals(getString(R.string.typeDeaf))) {
			return getString(R.string.typeSimpleOpen);
		} else if (button.getText().equals(getString(R.string.typeSimpleOpen))) {
			return getString(R.string.typeWind);
		}
		return getString(R.string.typeDeaf);
	}

	private List<String> getWindowImage() {
		List<String> list = new ArrayList<String>();
		for (int i = 0; i < windowImage.getChildCount(); i++) {
			Button button = (Button) windowImage.getChildAt(i);
			list.add(button.getText().toString());
		}

		return list;
	}

	protected abstract String getFormula();

	protected String getDialogMessage(String formula, double value, String usdRateString, boolean withFormula) {

		StringBuilder builder = new StringBuilder();
		if (withFormula) {
			builder.append(formula);
			builder.append("\n");
		}
		if (usdRateString.length() == 0) {
			usdRateString = "1";
		}
		builder.append(StringUtil.convertNumberToHumanFriednly(String.valueOf(value)) + " USD");
		builder.append("\n");
		double usdRate = Double.parseDouble(usdRateString);
		builder.append(StringUtil.convertNumberToHumanFriednly(String.valueOf(value * usdRate)) + " BYR");

		return builder.toString();
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		inflater.inflate(R.menu.main, menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getTitle().equals(getString(R.string.actionOpen))) {
			SQLDataManager.getInstance(getActivity()).getNames(new onLoadCompleteListener() {

				@Override
				public void onLoadComplete(List<String> resutl) {
					DialogUtil.showListDialog(getActivity(), R.string.chooseOrder, resutl, new onSelectCompleteListener() {

						@Override
						public void onSelected(String value) {
							SQLDataManager.getInstance(getActivity()).getOrder(value, new onLoadModelCompleteListener() {

								@Override
								public void onLoadComplete(CommonModel commonModel) {
									if (commonModel instanceof WindowModel) {
										((MainActivity) getActivity()).getWindowFragment().init(commonModel);
									} else if (commonModel instanceof DoorModel) {
										((MainActivity) getActivity()).getDoorFragment().init(commonModel);
									} else if (commonModel instanceof BalconyBlockModel) {
										((MainActivity) getActivity()).getBalconyBlockFragment().init(commonModel);
									} else if (commonModel instanceof BalconyRamaModel) {
										((MainActivity) getActivity()).getBalconyRamaFragment().init(commonModel);
									}
									if (commonModel.getWindowImage().size() >= 2) {
										showWindowImage(commonModel.getWindowImage().size(), commonModel.getWindowImage());
									}

								}
							});
						}
					});
				}
			});
		} else if (item.getTitle().equals(getString(R.string.actionSave))) {
			DialogUtil.showEditDialog(getActivity(), getString(R.string.enterName), 0, "", new onEditCompleteListener() {

				@Override
				public void onEditCompelted(String value) {
					CommonModel model = getModel();
					if (!(CommonFragment.this instanceof DoorFragment)) {
						model.setWindowImage(getWindowImage());

					}
					String json = new Gson().toJson(model);

					SQLDataManager.getInstance(getActivity()).addOrder(value, json, getTypeOrder());

				}

			});

		} else if (item.getTitle().equals(getString(R.string.actionClear))) {
			clear();
			if (!(this instanceof DoorFragment)) {
				showWindowImage(-1);
			}
		}
		return super.onOptionsItemSelected(item);
	}

	protected Integer getIntValue(String value) {
		if (value.length() == 0) {
			value = "0";
		}

		return Integer.valueOf(value);
	}

	protected Integer getIntValue(EditText editText) {
		return getIntValue(getValue(editText));
	}

	protected String getValue(EditText editText) {
		return editText.getText().toString();
	}

	protected String getValue(RadioGroup radioGroup) {

		if (radioGroup.getCheckedRadioButtonId() != -1) {
			int id = radioGroup.getCheckedRadioButtonId();
			View radioButton = radioGroup.findViewById(id);
			int radioId = radioGroup.indexOfChild(radioButton);
			RadioButton btn = (RadioButton) radioGroup.getChildAt(radioId);
			String selection = (String) btn.getText();
			return selection;
		}

		return "";
	}

	protected String getValue(Spinner spinner) {
		return spinner.getSelectedItem().toString();
	}

	protected void setValue(EditText editText, String value) {
		editText.setText(value);
	}

	protected void setEmptyValue(EditText editText) {
		editText.setText("");
	}

	protected void setEmptyValue(RadioGroup radioGroup) {

		if (radioGroup.getCheckedRadioButtonId() > 0) {

			radioGroup.clearCheck();
		}
	}

	protected void setEmptyValue(Spinner spinner) {
		spinner.setSelection(0);
	}

	protected void setValue(RadioGroup radioGroup, String value) {
		for (int i = 0; i < radioGroup.getChildCount(); i++) {
			RadioButton radioButton = (RadioButton) radioGroup.getChildAt(i);
			if (radioButton.getText().equals(value)) {
				radioButton.setChecked(true);
				break;
			}
		}
	}

	protected void setValue(Spinner spinner, String value) {
		for (int i = 0; i < spinner.getAdapter().getCount(); i++) {
			if (spinner.getAdapter().getItem(i).toString().equals(value)) {
				spinner.setSelection(i);
				break;
			}
		}
	}

	public void updateRate(String rate) {
		setValue(rateUsd, rate);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);
		lastTimeUpdate.setText(simpleDateFormat.format(new Date(System.currentTimeMillis())));
	}

	protected abstract void init(CommonModel commonModel);

	protected abstract CommonModel getModel();

	protected abstract void clear();

	protected abstract TypeOrder getTypeOrder();

}
